#pragma once
#ifndef COLLISION_H
#define COLLISION_H
#include <cmath>
#include <algorithm>

//碰撞箱类型
enum class CollisionBoxType {
    Point,
    Rectangle,
    Circle
};

// 前置声明
class PointCollisionBox;
class RectangleCollisionBox;
class CircleCollisionBox;

// 碰撞箱抽象基类
class CollisionBox {
public:
    CollisionBox();
    CollisionBox(CollisionBoxType type);
    virtual ~CollisionBox() = default;

    // 获取碰撞箱类型
    CollisionBoxType getType() const;

    // 纯虚函数：判断与其他碰撞箱是否碰撞
    virtual bool checkCollision(const CollisionBox& other) const = 0;

    // 虚函数：与具体类型碰撞箱的碰撞检测
    virtual bool checkCollisionWithPoint(const PointCollisionBox& point) const = 0;
    virtual bool checkCollisionWithRectangle(const RectangleCollisionBox& rect) const = 0;
    virtual bool checkCollisionWithCircle(const CircleCollisionBox& circle) const = 0;

    // 静态方法，检测任意两个碰撞箱的碰撞
    static bool checkCollision(const CollisionBox& box1, const CollisionBox& box2);

private:
    CollisionBoxType type_; //碰撞箱类型
};

// 点碰撞箱
class PointCollisionBox : public CollisionBox {
public:
    PointCollisionBox();
    PointCollisionBox(float x, float y);

    float getX() const;
    float getY() const;

    bool setX(float x);
    bool setY(float y);

    // 判断与其他碰撞箱是否碰撞
    bool checkCollision(const CollisionBox& other) const override;

    bool checkCollisionWithPoint(const PointCollisionBox& point) const override;
    bool checkCollisionWithRectangle(const RectangleCollisionBox& rect) const override;
    bool checkCollisionWithCircle(const CircleCollisionBox& circle) const override;

private:
    float x_, y_; //点坐标
};

// 矩形碰撞箱
class RectangleCollisionBox : public CollisionBox {
public:
    RectangleCollisionBox();
    RectangleCollisionBox(float x, float y, float width, float length);

    float getX() const;
    float getY() const;
    float getWidth() const;
    float getLength() const;

    bool setX(float x);
    bool setY(float y);
    bool setWidth(float width);
    bool setLength(float length);

    // 判断与其他碰撞箱是否碰撞
    bool checkCollision(const CollisionBox& other) const override;

    bool checkCollisionWithPoint(const PointCollisionBox& point) const override;
    bool checkCollisionWithRectangle(const RectangleCollisionBox& rect) const override;
    bool checkCollisionWithCircle(const CircleCollisionBox& circle) const override;

private:
    float x_, y_;       // 矩形左上角坐标
    float width_, length_;
};

// 圆形碰撞箱
class CircleCollisionBox : public CollisionBox {
public:

    CircleCollisionBox();
    CircleCollisionBox(float x, float y, float radius);

    float getX() const;
    float getY() const;
    float getRadius() const;

    bool setX(float x);
    bool setY(float y);
    bool setRadius(float radius);

    // 判断与其他碰撞箱是否碰撞
    bool checkCollision(const CollisionBox& other) const override;

    bool checkCollisionWithPoint(const PointCollisionBox& point) const override;
    bool checkCollisionWithRectangle(const RectangleCollisionBox& rect) const override;
    bool checkCollisionWithCircle(const CircleCollisionBox& circle) const override;

private:
    float x_, y_;  // 圆心坐标
    float radius_; // 圆形半径
};

#endif